home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
ASSEMBLER
/
BAOF
/
DemoNotes
Wrap
Text File
|
1994-10-26
|
25KB
|
627 lines
===========================================================================
BasicAOF version 1.20
© Oregan Software Developments 1994
===========================================================================
NOTE: This demonstration version of BasicAOF can only process the supplied
example files. This demo may be copied and given to others provided no
charge is made and all the files are copied and are unaltered in any way. PD
libraries may supply this demo as long as they do not charge more than £2
for a single disc including P&P.
BasicAOF is available now and costs £34.95 inclusive from:
Oregan Developments
36 Grosvenor Avenue
Streetly : Sutton Coldfield
B74 3PE
Tel: 0121 353 6044 (Access/Visa)
---------------------------------------------------------------------------
BasicAOF is a software development tool that enables Basic assembler to
export ARM Object Format (AOF) files.
These object files cannot be executed directly, but must first be linked
using a linker. It is most efficient to construct larger and more complex
programs from several object files, produced by BasicAOF and/or high level
compilers (C, Pascal, Fortran etc)
Mixing assembler and high level languages allows the construction of top
quality programs because you can take advantage of the strong points of both
worlds. For instance, writing most of the code in C allows you to exploit
the portability of C, the maintainability of C and the power of C libraries
and language. On the other hand, writing critical portions of code in Basic
assembler allows you to exploit all the speed of ARM processor and access
directly hardware or operating system.
Basic assembler is very popular because it is inbuilt in RISC OS ROM and is
interfaced with the BBC Basic interpreter in a way that allows for great
versatility. BasicAOF enables Basic assembler to:
• be invoked in multi-tasking mode
• save ARM Object Format files
• export global-scope symbols
• import external symbols
• relocate position-dependent code automatically at link time
• debug from Basic environment, in-memory-assembled code using Desktop
Debugger Tool (DDT)
• re-assemble AOF files produced from C compiler or other code
generators using DsasmBAOF disassembler
Combining Basic assembler and BasicAOF you can use all the features provided
in conventional assemblers and more besides, as the Basic interpreter has
greater flexibility:
• repetitive assembly
• macro assembly
• conditional assembly
• global and local label capability
• comprehensive expression handling (including floating point
expressions)
• rich operator and function set (including indirection operators)
• save any section of memory as AOF
• encapsulation of any binary file in generated AOF (e.g you can load
a spritefile and generate exported symbols for the address of each
sprite, or load a template definition and create a relocatable AOF
with symbols for each window)
• Implementation of code generators facility (e.g. create optimised
code plotting a particular sprite)
You can find all the above features demonstrated in the example programs
supplied.
References and terminology
==========================
It is assumed that reader is familiar with the following topics:
a) definition of APCS
b) using Link DDE tool
c) using Make/AMU DDE tools
d) using DDT debugger
e) using BBC Basic Assembler
Topics a), b), c), d) are addressed in Desktop Development Environment User
Guide published by Acorn Computers Ltd.
Topics a), b), e) are addressed in Appendixes of RISC OS 2/3 Programmer's
Reference Manual published by Acorn Computers Ltd.
The following terms and abbreviations are often used in the text:
AIF
Application Image Format. Executable RISC OS applications produced
by Link DDE tool.
ALF
Acorn Library Format. A collection of AOF files constructed from a
set of AOF files by the LibFile DDE tool.
AMU
Acorn Make Utility DDE tool. It is a tool managing the construction
of executable program images, modules and libraries. It avoids
needless re-processing of unaltered source files and ensures
consistent construction using operations and dependencies specified
in a Makefile.
AOF
ARM Object Format. A code file format generated by BasicAOF,
compilers and assemblers.
APCS
ARM Procedure Call Standard. This is a contract between two
procedures, one calling the other. The called procedure needs to
know which registers it can freely change without restoring them
before returning, and the caller needs to know which registers it
can rely on not being corrupted over a procedure call. Additionally
both procedures need to know which registers contain input arguments
and return arguments, and the arrangement of stack backtrace data.
Writing assembly language procedures that obey APCS is the key to
interworking C and assembler.
DDE
Desktop Development Environment. An extendable set of RISC OS
Desktop tools for developing applications and relocatable modules,
developed by Acorn Computers Ltd.
DDT
Desktop Debugging Tool. An advanced interactive aid to debugging
programs written in compiled languages and/or ARM assembler.
Libfile
A library management DDE tool. It can be used to create and maintain
library archives (ALF files).
Link
The ARM linker tool supplied as part of DDE. Link tool accepts a set
of AOF and ALF files as input and produces an AIF executable or a
Relocatable Module as output.
Make
An interactive DDE tool that aids the programmer in the construction
and maintenance of Makefiles.
Objasm
ARM AOF assembler developed by Acorn Computers Ltd forming part of
the Desktop Assembler product.
RISC_OSLib
A library supplied with Acorn's ANSI C compiler, designed to help
program applications to run under the desktop.
Loading BasicAOF
================
BasicAOF is compatible with RISC OS 2 and RISC OS 3 and needs SharedCLibrary
module version 3.75 or later. When you double click the !BasicAOF icon,
BasicAOF will be installed as a relocatable module.
It is assumed you have already installed DDE on your system in order to be
able to use linking and managed compilation facilities. Programmers who want
to program only using BasicAOF without using any compiled language, at least
should install Link tool and Make/AMU tool from DDE tools.
BasicAOF has extremely low memory requirements. Resident program code and
workspace consume less than 19Kb in module area and memory is dynamically
allocated, so more memory will be used only if really needed. As a result it
is quite usable on smaller machines (1 MB RAM and floppy disc)
Using BasicAOF
==============
There are many features in BasicAOF but it is not possible to document the
program fully in these notes. BasicAOF provides several SWIs for use in
Basic assembler programs. The calls that probably will be used more
frequently are:
SYS "BasicAOF_Export"
SYS "BasicAOF_SaveAOF"
You can also call some BasicAOF SWIs via assembler macros that call directly
the appropriate SWIs. Such macros are:
FNimport(symbol$)
FNweak(symbol$)
FNreloc(label%)
FNdebug(address%)
Let's demonstrate some of the above calls in a minimal example:
REM >Prog1
DIM code% 1000, L%-1
FOR pass=8 TO 10 STEP 2:P%=code%:[OPT pass
.beep
MOV r0, #7
SWI "OS_WriteC"
MOVS pc, r14
]:NEXT
To export this trivial procedure with name "beep_proc" we should append the
following line in the end of the program:
SYS "BasicAOF_Export", "beep_proc", beep
However this statement does not actually save the AOF file, thus after
exporting all the symbols we want, we should add the following line:
SYS "BasicAOF_SaveAOF", code%, P%
This call specifies the start address of code and the end address of code.
If the Basic source resides in 's' directory, the resulting AOF file will be
saved in 's.^.o' directory.
The exported procedure "beep_proc" can now be called from other C or
Assembler programs such as the one below:
REM >Prog2
DIM code% 1000, L%-1
FOR pass=8 TO 10 STEP 2:P%=code%:[OPTpass
.entry_address
BL FNimport("beep_proc")
SWI "OS_Exit"
]:NEXT
SYS "BasicAOF_SaveAOF", code%, P%,,, entry_address
END
DEF FNimport(symbol$)
IF (pass AND 2) SYS "BasicAOF_Import", symbol$, P%
=0
Here we have used FNimport() macro to call the symbol that was exported from
Prog1. We have also specified an entry address which is the execution
address for the whole program contained in these two short source files.
In order to obtain the final executable, we must run the programs s.Prog1
and s.Prog2 and then link the object files using the following command:
Link -o !RunImage o.Prog1 o.Prog2
Please note that code or data contained in AOF files must be relocatable,
because the linker will position the contents of object files at an
arbitrary location in the final executable. Thus if the code contains
position dependent data (absolute pointers etc), you can use FNreloc to
provide automatic relocation at linking stage. Instead of writing 'DCD
pointer%' write 'DCD FNreloc(pointer%)' in your code, where pointer% is a
program-relative address.
Working styles
==============
• Unmanaged Development
If you want to assemble a Basic source in unmanaged development style, just
double click on the Basic file to run it. The AOF file produced will be
saved with the default filename described above. This style can offer the
quickest way of constructing small and simple programs.
• Managed Development
This working style makes use of Makefiles to manage the construction of your
programs. The DDE tools Make and AMU can both execute the commands in a
Makefile running other tools to perform the make job. The Make tool also
constructs Makefiles for you, avoiding the need for you to understand their
syntax, and making it quick and easy to do this.
The main advantages of managed development are that no unnecessary
reprocessing of unaltered program sources is performed and programs are
constructed consistently even when run by different people on different
systems. These advantages make managed development the best style for the
development of larger programs with code split into several source files.
In order to use BasicAOF through Make/AMU, the Basic assembler sources must
reside in a directory named 's' inside your Work Directory. An Objasm
command will be invoked from AMU that will be trapped if the source is a
Basic file and this file will be executed. Otherwise Objasm will be called
with identical arguments. As a result mixed processing of BasicAOF and
Objasm assembler sources is enabled.
In addition please note that in managed development style, the Basic
assembler multitasks under the RISC OS desktop, allowing other tasks to
proceed while it operates.
DDT debugging
=============
If you wish to debug your final executable program with the DDT debugger,
Link tool must be invoked with Debug option selected.
Executing a binary produced in the above way, or dragging it onto the DDT
icon starts a debugging session on it. Of course debugging will be at
machine level (i.e. displaying the current execution position on a
disassembly of memory).
All global-scope symbols exported with BasicAOF will be shown in the DDT
disassembling window. If you want to add more local-scope symbols to aid
debugging, use SWI BasicAOF_Keep.
Also please note that SWI BasicAOF_Debug provides a direct call to DDT from
Basic assembler without forcing you to link the final executable program.
Consequently testing and debugging a Basic assembler routine is made much
easier and faster. You can see example '!BasicDDT' to understand how
BasicAOF_Debug is used via FNdebug(address%) macro.
Making your own linkable libraries
==================================
Linkable libraries (ALF files) are collections of many AOF files stored in
one file. When presented to linker as an input file, the referenced object
files within a library are linked onto the output executable, but those not
needed are left out. A linkable library is therefore a recommended way of
storing a selection of useful procedures for re-use in a number of programs.
You may well find that this facility can save you a lot of time by avoiding
continually 'reinventing the wheel'. You will need the Libfile DDE tool to
construct and modify linkable libraries.
You can collect object files produced with BasicAOF in libraries. If you
want to interwork your routines with other compiled languages like C, they
must obey APCS.
Utilities
=========
The full version of the package includes also DsasmBAOF, a typical
non-interactive DDE tool that disassembles AOF files and generates BasicAOF
assembler source files. The program uses all available information to
construct the closest representation of the original source and handles
automatically the following data contained in AOF file:
• Global and local symbol information
• Relocation directives (type 1 PC-relative & additive)
• Automatic handling of Bcc/BLcc instructions
• Automatic handling of instructions ADRcc Rx,label/LDRcc Rx,label
• Automatic generation of appropriate labels
• Automatic handling of ASCII literal strings
• Supports CODE, DATA and NOINIT areas. DEBUG areas are ignored.
• FPE instructions displayed as data and comments
• APCS-RISC OS register bindings used for displaying assembler output
You can examine AOF files extracted from libraries like RISC_OSLib or
AnsiLib. DsasmBAOF is also useful for converting C programs to Basic
assembler, in order to optimise or modify the generated code.
BasicAOF Examples
=================
If you want to understand quickly how BasicAOF is used, you can study the
supplied well-documented example programs.
Please note that considerable effort has been expended to provide useful and
non-trivial examples, to demonstrate all features of BasicAOF with C
compiler or standalone. All examples are cases where ARM code is essential
for speed or low-level reasons.
If you want to re-build the example programs double click on the relevant
Makefile inside each Work Directory. The following sections describe the
interesting points demonstrated in example programs:
Wave3d
======
This is the simplest example as far as BasicAOF is concerned. The program
consists of three short assembler sources and a main C source.
s.intsqr
This is a leaf procedure (one that calls no other procedures)
computing the square root of an unsigned 32 bit number. It has been
thoroughly optimised because it is called more than 2500 times per
frame. This is a typical example of a procedure that must be written
in ARM assembler for efficiency reasons.
s.blitlines
A simple procedure clearing video ram extremely fast. C code can not
achieve the speed obtained with ARM assembler, when reading or
writing memory blocks.
s.Sin
In this example, floating point expressions and indirection
operators are used to access memory directly, in order to construct
a lookup table of fixed point Sine values.
This particular example can't be written in a conventional
assembler. The closest you can get, is to write a program to create
a binary file that will be loaded at assembly/run time, a technique
which does not fit well in the automatic process of managed
compilation.
UnSqueeze
=========
s.call_unsq
A low-level procedure obeying APCS that calls code which corrupts
all 16 ARM registers. Such low-level operations can not be easily
written in C, but are simple in assembly.
Wallpaper
=========
s.Wallpaper
Here is demonstrated, how to develop and debug an assembler routine
in Basic environment and then export it with BasicAOF. Developing
and debugging code is much easier in Basic environment compared with
a conventional assembler, because you don't have to modify the
source file, invoke the assembler, link a routine that will supply
parameters to the developed procedure and finally run the
executable.
Modify variable debug% and run the program to see the routine
executed in Basic. In addition you can see how macro assembly and
conditional assembly can be implemented in Basic assembler.
Bases
=====
s.Bases
This is a simple multi-tasking RISC OS application, contained in a
short Basic assembler source file. However all Wimp handling is
performed calling functions from RISC_OSLib, a library developed in
C by Acorn.
All RISC_OSLib and SharedCLibrary functions are called via
FNimport() macro. The only exported symbol is "main" which is the
name of the entry function in any C program.
Parallax
========
s.blitstripe
This is a procedure obeying APCS which has 6 input arguments and
here is demonstrated how to load 5th and 6th arguments from stack.
Additionally FNreloc() macro is used to relocate an array of
pointers. Repetitive assembly and macro assembly are used in this
example too.
Also please note that symbol "screenbase" exported in this source is
not a function, but an integer variable that will be initialised in
the C part of program.
s.ShiftPic
In this example, a spritefile is loaded in memory and three shifted
copies are created. Subsequently the bitmap addresses of each sprite
are exported.
Using this technique you can encapsulate any binary file (optionally
processing it in any way) within an AOF file that will be linked
into the executable.
This will allow you to include data, text, sprites, templates,
drawfiles etc. inside the !RunImage file of your application. In
addition you can use FNreloc() macro to convert any datafile
containing pointers, into a relocatable AOF file that can be
positioned by the linker anywhere in the final executable (for
example Template files).
Also please note that in '!Parallax.Makefile' we have established a
dependency between 's.ShiftPic' assembler source and 'dat.Picture’
sprite file. As a result, whenever the sprite file is altered,
Make/AMU will re-assemble 's.ShiftPic'.
Exiter
======
You can assemble a module from a set of source files, a link step being
required to join the produced AOF files to form the usable relocatable
module. Exiter is a relocatable module split into three assembler sources. C
language is not used in this example.
The separation of routines into separately assembled files has many
advantages (e.g. better maintenance and debugging) . Additionally since DDT
cannot be used to debug modules, it can be useful to link routines into test
applications, debug them with DDT, then link them into the module.
It is a good idea to construct a module with the module header and the small
routines/data associated with it in one source file, to be linked with the
other source files forming the body of the module.
s.RM_Header
This is a general module header which you can adjust to form the
headers of other relocatable modules. This module header file must
be linked so that it is placed first in the module binary. To do
this you should use the following statement:
SYS "BasicAOF_SaveAOF", code%, P%, "!!!Module$$Header",&2202
Provided that areas are sorted by type and name, a name beginning
with '!' is placed before an alphabetic name, so the above call can
be used to ensure first placing.
The module header source needs to contain FNimport() macros making
available any symbols referenced in the module body. In addition,
the initialisation routine should call, before anything else,
__RelocCode, a routine added by the linker which relocates any
absolute references to symbols when the module is initialised.
s.ModuleBody
Main section of module, comprising of Start, Initialisation,
Finalisation and Service handlers.
s.Keyevent
The useful part of module. You can easily alter this part in order
to perform other tasks like screen grabbing, volume control etc.
ColorBars
=========
This is an example demonstrating some advanced uses of BasicAOF. It consists
of five assembler sources and a main C part.
It is interesting to note that AOF file C:o.stubs, which contains the
vectors of SharedCLibrary functions, is not linked in the final executable.
Instead a minimal Run-Time System Kernel is used to interface C with
operating system. As a result this C program is self-contained and does not
require SharedCLibary module or AnsiLib library. This can be very useful in
some situations.
s.miniRTSK
This assembler source implements an absolutely minimal Run-Time
System Kernel that must be initialised before C "main" function is
entered. That's why an entry address is defined in this file, which
will be the execution address for the whole program.
First of all we have to setup stack pointer (sp) and stack limit
(sl) registers, needed by C code. A simple descending non-extendable
stack is initialised and an appropriate stack overflow procedure is
defined. User may set the initial stack size by defining a global
variable in C named "stack_size". However if this variable is not
defined, a default stack size of 2Kb is set. In order to detect if
user has defined stack_size variable, symbol is referenced with
FNweak() macro. If you specify in C source a small stack size, stack
overflow error will be raised.
Another interesting point is that in order to find the end of code
and data in the final executable, the predefined linker symbol
"Image$$RW$$Limit" is referenced. During linking stage, Link will
assign to this symbol the end address of read-write section of
image. As a result all memory above this address will not be used so
we can setup there our stack. You can find out more about Linker
pre-defined symbols, in DDE User Guide in the chapter titled "Link".
s.xswi
This is a simple but fast SWI veneer, to interface C with operating
system SWI calls.
s.Border
A procedure changing screen border colour by accessing directly VIDC
registers in SVC processor mode. Of course such low-level operations
must be written in assembler and not C. Please note that the border
colour is used as a CPU-load indicator.
s.blitline
A solution to the problem of unique macro labels in Basic assembler.
Local label capability is incorporated in some conventional
assemblers, but with effective use of Basic interpreter, it can be
implemented in Basic assembler too.
s.RGBmask
A very useful code generator example. In this example a sprite is
loaded in memory and specially optimised code depending on the
sprite shape, is generated and saved as an AOF file.
In fact, using this technique you can implement simple compilers and
code generators producing AOF files via BasicAOF. For example you
can implement the CMHG (C Module Header Generator) using this
technique.
Finally note that whenever the sprite file is modified, the
optimised code will be re-assembled, because we have established a
Makefile dependency similar to the !Parallax example.
BasicDDT
========
An example demonstrating how to call DDT interactive debugger from Basic
environment to make debugging easier and faster.
You should have loaded DDT before running this program. After running the
program, DDT is entered and registers R0-R13 have the same values setup by
Basic's CALL/USR statement, i.e. R0-R7 = A%-H%.
In DDT you can singlestep instructions, set breakpoints or watchpoints,
trace execution, change registers or memory contents, evaluate expressions
etc.
When the end of assembler routine is reached, you should choose Quit entry
from DDT's menu to return back to Basic environment. Registers R0-R13 after
quitting DDT, are identical to the values on exit from routine.